package cn.jiaqiang.chatgpt.data.trigger.http;

import cn.jiaqiang.chatgpt.data.domain.auth.service.IAuthService;
import cn.jiaqiang.chatgpt.data.domain.openai.model.aggregates.ChatProcessAggregate;
import cn.jiaqiang.chatgpt.data.domain.openai.model.entity.MessageEntity;
import cn.jiaqiang.chatgpt.data.domain.openai.service.chat.IChatService;
import cn.jiaqiang.chatgpt.data.trigger.http.dto.*;
import cn.jiaqiang.chatgpt.data.types.common.Constants;
import cn.jiaqiang.chatgpt.data.types.exception.ChatGPTException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@Slf4j
@RestController()
@CrossOrigin("${app.config.cross-origin}")
@RequestMapping("/api/${app.config.api-version}/")
public class ChatGPTAIServiceController {

    @Resource
    private IChatService chatService;

    @Resource
    private IAuthService authService;

    /**
     * 短视频脚本
     */
    @RequestMapping(value = "chat/shot/video", method = RequestMethod.POST)
    public ResponseBodyEmitter completionsStream(@RequestBody ChatShortVideoRequestDTO request, @RequestHeader("Authorization") String token, HttpServletResponse response) {
        log.info("流式问答请求开始，使用模型：{} 请求信息：{}", request.getModel(), JSON.toJSONString(request.getMessages()));
        try {
            // 1. 基础配置；流式输出、编码、禁用缓存
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");

            // 2. 构建异步响应对象【对 Token 过期拦截】
            ResponseBodyEmitter emitter = new ResponseBodyEmitter(3 * 60 * 1000L);
            boolean success = authService.checkToken(token);
            if (!success) {
                try {
                    emitter.send(Constants.ResponseCode.TOKEN_ERROR.getCode());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                emitter.complete();
                return emitter;
            }
            String userId = authService.userId(token);;
            if (userId == null) {
                emitter.send(Constants.ResponseCode.TOKEN_ERROR.getCode());
                emitter.complete();
                throw new ChatGPTException("userId 解析出错.");
            }
            log.info("流式问答请求处理，userId: {} 请求模型: {}", userId, request.getModel());

            // 5. 构建参数
            ChatProcessAggregate chatProcessAggregate = ChatProcessAggregate.builder()
                    .token(token)
                    .userId(userId)
                    .model(request.getModel())
                    .messages(request.getMessages().stream()
                            .map(messageEntityDTO -> MessageEntity.builder()
                                    .role(messageEntityDTO.getRole())
                                    .content(request.isController() ? buildRequestMessagePlus(messageEntityDTO.getContent()) : buildRequestMessage(messageEntityDTO))
                                    .build())
                            .collect(Collectors.toList()))
                    .build();

            // 4. 请求结果&返回
            return chatService.completions(emitter, chatProcessAggregate);
        } catch (Exception e) {
            log.error("流式应答，请求模型：{} 发生异常", request.getModel(), e);

            throw new ChatGPTException(e.getMessage());
        }
    }
    /**
     * 构建短视频脚本的请求参数
     * @return 视频脚本的请求参数 message
     */
    private String buildRequestMessage(ChatShortVideoEntityDTO messageEntityDTO) {
        String message = "你好，请给我生成一个短视频剧本，要求如下：";
        return message.concat("短视频主题为：").concat(messageEntityDTO.getTheme())
                .concat("短视频结构为：").concat(messageEntityDTO.getStruct())
                .concat("短视频情感基调为：").concat(messageEntityDTO.getEmotion())
                .concat("短视频主要事件为：").concat(messageEntityDTO.getScene())
                .concat("短视频剧本的表演时间约为：").concat(messageEntityDTO.getTotalTime())
                .concat(", 谢谢你~我对短视频很感兴趣，希望你可以生成一个我满意的短视频剧本");
    }


    /**
     * 文章生成 - 自定义
     */
    @RequestMapping(value = "chat/essay/init/custom", method = RequestMethod.POST)
    public ResponseBodyEmitter completionsStream(@RequestBody ChatEssayRequestDTO request, @RequestHeader("Authorization") String token, HttpServletResponse response) {
        log.info("流式问答请求开始，使用模型：{} 请求信息：{}", request.getModel(), JSON.toJSONString(request.getMessages()));
        try {
            // 1. 基础配置；流式输出、编码、禁用缓存
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");

            // 2. 构建异步响应对象【对 Token 过期拦截】
            ResponseBodyEmitter emitter = new ResponseBodyEmitter(3 * 60 * 1000L);
            boolean success = authService.checkToken(token);

            if (!success) {
                try {
                    emitter.send(Constants.ResponseCode.TOKEN_ERROR.getCode());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                emitter.complete();
                return emitter;
            }
            // 3. 获取 userId
            String userId = authService.userId(token);
            if (userId == null) {
                throw new ChatGPTException("userId 解析出错.");
            }
            log.info("流式问答请求处理，userId: {} 请求模型: {}", userId, request.getModel());

            // 5. 构建参数
            ChatProcessAggregate chatProcessAggregate = ChatProcessAggregate.builder()
                    .token(token)
                    .userId(userId)
                    .model(request.getModel())
                    .messages(Stream.of(request.getMessages().get(Math.max(request.getMessages().size() - 1, 0)))
                            .map(messageEntityDTO -> MessageEntity.builder()
                                    .role(messageEntityDTO.getRole())
                                    .content(buildEssayRequestMessage(messageEntityDTO))
                                    .build())
                            .collect(Collectors.toList()))
                    .build();
            // 4. 请求结果&返回
            return chatService.completions(emitter, chatProcessAggregate);
        } catch (Exception e) {
            log.error("流式应答，请求模型：{} 发生异常", request.getModel(), e);
            throw new ChatGPTException(e.getMessage());
        }
    }
    /**
     * 构建 文章生成 的请求参数
     * @return 文章生成 的请求参数 message
     */
    private String buildEssayRequestMessage(ChatEssayEntityDTO messageEntityDTO) {
        String message = "你好，请给我生成一篇文章";
        if (StringUtils.hasLength(messageEntityDTO.getContentStyle())) {
            message = message.concat("文章题材为：").concat(messageEntityDTO.getContentStyle()).concat(",");
        }
        if (StringUtils.hasLength(messageEntityDTO.getEmotionalTone())) {
            message = message.concat("文章总体感情基调为：").concat(messageEntityDTO.getEmotionalTone()).concat(",");
        }
        if (messageEntityDTO.getNumberOfWords() != null) {
            int count = messageEntityDTO.getNumberOfWords();
            if (count < 500) {
                count += count / 2;
            } else if (count <= 800) {
                count *= 2;
            } else if (count <= 1000) {
                count = (count * 3);
            } else if (count <= 1200) {
                count = (count * 4);
            } else if (count <= 1500) {
                count = count * 5;
            } else {
                count = 1500 * 5;
            }
            message = message.concat("文章字数为：").concat(String.valueOf(count)).concat(",");
        } else {
            message = message.concat("文章字数为：").concat("800").concat(",");
        }
        if (StringUtils.hasLength(messageEntityDTO.getTopicsAndKeywords())) {
            message = message.concat("主题关键字：").concat(messageEntityDTO.getTopicsAndKeywords()).concat(",");
        }

        return message.concat("谢谢你~这篇文章对我很重要，希望你可以生成一个我满意的文章。");
    }



    /**
     * 文章生成 - 只根据题目生成
     */
    @RequestMapping(value = "chat/essay/init", method = RequestMethod.POST)
    public ResponseBodyEmitter completionsStream(@RequestBody ChatArticleInitRequestDTO request, @RequestHeader("Authorization") String token, HttpServletResponse response) {
        log.info("流式问答请求开始，使用模型：{} 请求信息：{}", request.getModel(), request.getTitle());
        try {
            // 1. 基础配置；流式输出、编码、禁用缓存
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");

            // 2. 构建异步响应对象【对 Token 过期拦截】
            ResponseBodyEmitter emitter = new ResponseBodyEmitter(3 * 60 * 1000L);
            boolean success = authService.checkToken(token);

            if (!success) {
                try {
                    emitter.send(Constants.ResponseCode.TOKEN_ERROR.getCode());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                emitter.complete();
                return emitter;
            }
            // 3. 获取 userId
            String userId = authService.userId(token);
            if (userId == null) {
                throw new ChatGPTException("userId 解析出错.");
            }
            log.info("流式问答请求处理，userId: {} 请求模型: {}", userId, request.getModel());

            // 5. 构建参数
            ChatProcessAggregate chatProcessAggregate = ChatProcessAggregate.builder()
                    .token(token)
                    .userId(userId)
                    .model(request.getModel())
                    .messages(Collections.singletonList(MessageEntity.builder()
                            .role(request.getRole())
                            .content(buildInitRequestMessage(request.getTitle()))
                            .build()))
                    .build();
            // 4. 请求结果&返回
            return chatService.completions(emitter, chatProcessAggregate);
        } catch (Exception e) {
            log.error("流式应答，请求模型：{} 发生异常", request.getModel(), e);
            throw new ChatGPTException(e.getMessage());
        }
    }
    private String buildInitRequestMessage(String title) {
        return "你好，我现在需要生成一篇作文，题目是：" + title + ", 希望你可以通过这个题目解析出一些关键词，并"
                + "通过这些关键词生成一篇作文，谢谢你。";
    }


    /**
     * 文章润色
     */
    @RequestMapping(value = "chat/article/edit", method = RequestMethod.POST)
    public ResponseBodyEmitter completionsStream(@RequestBody ChatArticleRequestDTO request, @RequestHeader("Authorization") String token, HttpServletResponse response) {
        log.info("流式问答请求开始，使用模型：{} 请求信息：{}", request.getModel(), JSON.toJSONString(request.getMessages()));
        try {
            // 1. 基础配置；流式输出、编码、禁用缓存
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");

            // 2. 构建异步响应对象【对 Token 过期拦截】
            ResponseBodyEmitter emitter = new ResponseBodyEmitter(3 * 60 * 1000L);
            boolean success = authService.checkToken(token);

            if (!success) {
                try {
                    emitter.send(Constants.ResponseCode.TOKEN_ERROR.getCode());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                emitter.complete();
                return emitter;
            }
            // 3. 获取 userId
            String userId = authService.userId(token);
            if (userId == null) {
                throw new ChatGPTException("userId 解析出错.");
            }
            log.info("流式问答请求处理，userId: {} 请求模型: {}", userId, request.getModel());

            // 5. 构建参数
            ChatProcessAggregate chatProcessAggregate = ChatProcessAggregate.builder()
                    .token(token)
                    .userId(userId)
                    .model(request.getModel())
                    .messages(Stream.of(request.getMessages().get(Math.max(request.getMessages().size() - 1, 0)))
                            .map(messageEntityDTO -> MessageEntity.builder()
                                    .role(messageEntityDTO.getRole())
                                    .content(buildArticleRequestMessage(messageEntityDTO))
                                    .build())
                            .collect(Collectors.toList()))
                    .build();

            // 4. 请求结果&返回
            return chatService.completions(emitter, chatProcessAggregate);
        } catch (Exception e) {
            log.error("流式应答，请求模型：{} 发生异常", request.getModel(), e);
            throw new ChatGPTException(e.getMessage());
        }
    }

    /**
     * 构建 文章润色 的请求参数
     * @return 文章润色 的请求参数 message
     */
    private String buildArticleRequestMessage(ChatArticleEntityDTO messageEntityDTO) {
        int count = messageEntityDTO.getFontNumber();
        if (count < 500) {
            count += count / 2;
        } else if (count <= 800) {
            count *= 2;
        } else if (count <= 1000) {
            count = (count * 3);
        } else if (count <= 1200) {
            count = (count * 4);
        } else if (count <= 1500) {
            count = count * 5;
        } else {
            count = 1500 * 5;
        }
        String message = "你好，请帮我对以下这这篇文章进行精修：".concat(messageEntityDTO.getUnmodifiedText()).concat("。要求如下：");

        if (StringUtils.hasLength(messageEntityDTO.getModifiedStyle())) {
            message = message.concat("精修后的润色风格为：").concat(messageEntityDTO.getModifiedStyle()).concat(",");
        }
        if (StringUtils.hasLength(messageEntityDTO.getEmotionalTone())) {
            message = message.concat("精修后的感情基调为：").concat(messageEntityDTO.getEmotionalTone()).concat(",");
        }
        if (StringUtils.hasLength(messageEntityDTO.getModifiedLevel())) {
            message = message.concat("精修强度为：").concat(messageEntityDTO.getModifiedLevel()).concat(",");
        }
        return message
                .concat("文章润色字数至少超过：").concat(String.valueOf(count)).concat("字, 请认真修改，这对我来说很重要，谢谢你~")
                ;
    }


    /**
     * 调优
     */
    private String buildRequestMessagePlus(String content) {
        return "你好，这次的生成结果我不太满意，请基于刚刚的结果进行调优，要求如下：" + content + ",谢谢你。";
    }

    /**
     * 流式问题，ChatGPT 请求接口
     * <p>
     * curl -X POST \
     * http://localhost:8090/api/v1/chat/completions \
     * -H 'Content-Type: application/json;charset=utf-8' \
     * -H 'Authorization: b8b6' \
     * -d '{
     * "messages": [
     * {
     * "content": "写一个java冒泡排序",
     * "role": "user"
     * }
     * ],
     * "model": "gpt-3.5-turbo"
     * }'
     */
    @RequestMapping(value = "chat/completions", method = RequestMethod.POST)
    public ResponseBodyEmitter completionsStream(@RequestBody ChatGPTRequestDTO request, @RequestHeader("Authorization") String token, HttpServletResponse response) {
        log.info("流式问答请求开始，使用模型：{} 请求信息：{}", request.getModel(), JSON.toJSONString(request.getMessages()));
        try {
            // 1. 基础配置；流式输出、编码、禁用缓存
            response.setContentType("text/event-stream");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Cache-Control", "no-cache");

            // 2. 构建异步响应对象【对 Token 过期拦截】
            ResponseBodyEmitter emitter = new ResponseBodyEmitter(3 * 60 * 1000L);
            boolean success = authService.checkToken(token);

            if (!success) {
                try {
                    emitter.send(Constants.ResponseCode.TOKEN_ERROR.getCode());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                emitter.complete();
                return emitter;
            }
            // 3. 获取 userId
            String userId = authService.userId(token);
            if (userId == null) {
                throw new ChatGPTException("userId 解析出错.");
            }
            log.info("流式问答请求处理，userId: {} 请求模型: {}", userId, request.getModel());

            // 5. 构建参数
            ChatProcessAggregate chatProcessAggregate = ChatProcessAggregate.builder()
                    .token(token)
                    .userId(userId)
                    .model(request.getModel())
                    .messages(request.getMessages().stream()
                            .map(messageEntityDTO -> MessageEntity.builder()
                                    .role(messageEntityDTO.getRole())
                                    .content(messageEntityDTO.getContent())
                                    .name(messageEntityDTO.getName())
                                    .build())
                            .collect(Collectors.toList()))
                    .build();

            // 4. 请求结果&返回
            return chatService.completions(emitter, chatProcessAggregate);
        } catch (Exception e) {
            log.error("流式应答，请求模型：{} 发生异常", request.getModel(), e);
            throw new ChatGPTException(e.getMessage());
        }
    }

}
